using System;
using System.Reflection;
using CKS.EBE.Logging;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint;
using System.Xml;
using CKS.EBE.API;
using System.Web.UI;
using System.Diagnostics;
using System.Xml.Xsl;

namespace CKS.EBE.WebControls
{
	public class XmlBasedControl : SPControl, IXmlDocumentDataSource
	{
		private XslTransformation _transform;
		private XmlDocument _document;
		private SPWeb _web;
		private EBECache _cache;

		public EBECache Cache
		{
			get { if (_cache == null) _cache = new EBECache(UniqueID); return _cache; }
			set { _cache = value; }
		}
		public string XmlDataSource { get; set; }

		public XmlDocument Document
		{
			get
			{
				if (_document != null) return _document;

				if (Cache.IsCached)
					_document = (XmlDocument)Cache.Value;

				else if (!string.IsNullOrEmpty(XmlDataSource))
					_document = GetDataSourceDocument();
				else
					_document = BuildDocument();

				if (Cache.Enabled) Cache.Value = _document;

				return _document;
			}
			set { _document = value; }
		}

		protected virtual XmlDocument BuildDocument() { return null; }

		protected virtual XmlDocument GetDataSourceDocument()
		{
			XmlDocument oError = new XmlDocument();
			oError.LoadXml("<Error/>");

			try
			{
				if (XmlDataSource == ID) return BuildDocument();

				Control c = NamingContainer.FindControl(XmlDataSource);

				if (c == null)
					oError.InnerText = "XmlDataSource not found";
				else if (c is IXmlDocumentDataSource)
					return ((IXmlDocumentDataSource)c).Document;
				else
					oError.InnerText = "Invalid XmlDataSource";
			}
			catch (Exception ex)
			{
				Trace.Write(ex);
				oError.InnerText = ex.Message;
			}

			return oError;
		}

		public XslTransformation Transform
		{
			get { if (_transform == null) _transform = new XslTransformation(); return _transform; }
			set { _transform = value; }
		}

		protected SPWeb Web
		{
			[DebuggerStepThrough]
			get
			{
				if (_web == null) _web = SPContext.Current.Web;
				return _web;
			}
		}

		protected string ThemeName
		{
			get { return BlogContext.Current.BlogTheme; }
		}

		protected string ThemeVariation
		{
			get { return BlogContext.Current.BlogThemeVariation; }
		}

		protected override void Render(HtmlTextWriter writer)
		{
			try
			{
				Transform.CacheID = UniqueID;
				Transform.Document = Document;
				Transform.RenderControl(writer);
			}
			catch (Exception ex)
			{
				Logger.Error(new SPException("CKS:EBE - Error rendering a control: " + ex.Message, ex), "XmlBasedControl.Render");
				throw new SPException(ex.Message, ex);
			}
		}

		/// <summary>
		/// remove ows_
		/// </summary>
		/// <param name="xml"></param>
		/// <returns></returns>
		protected static XmlDocument CleanXml(string xml)
		{
			XmlDocument oDoc = new XmlDocument();
			oDoc.LoadXml(xml);
			CleanXml(oDoc);
			return oDoc;
		}

		/// <summary>
		/// remove ows_
		/// </summary>
		/// <param name="xml"></param>
		protected static void CleanXml(XmlDocument xml)
		{
			XmlTextReader oReader = new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("CKS.EBE.Resources.CleanXml.xsl"));
			XslCompiledTransform oTransform = new XslCompiledTransform();
			oTransform.Load(oReader);

			System.IO.StringWriter sw = new System.IO.StringWriter();

			XmlTextWriter writer = new XmlTextWriter(sw);
			oTransform.Transform(xml, null, writer);
			xml.LoadXml(sw.ToString());
		}
	}
}